//package com.example.test.listener;
//
//import org.slf4j.Logger;
//import org.slf4j.LoggerFactory;
//import org.springframework.boot.SpringApplication;
//import org.springframework.boot.SpringApplicationRunListener;
//import org.springframework.boot.context.event.ApplicationEnvironmentPreparedEvent;
//import org.springframework.context.ConfigurableApplicationContext;
//import org.springframework.core.env.ConfigurableEnvironment;
//import org.springframework.core.env.Environment;
//import org.springframework.core.env.MapPropertySource;
//import org.springframework.core.io.support.SpringFactoriesLoader;
//
//import java.time.LocalDateTime;
//import java.time.format.DateTimeFormatter;
//import java.util.Properties;
//
///**
// * 自定义 Spring Boot 启动监听器
// * 作用：在应用启动各阶段执行审计、校验、通知逻辑
// * 关键特性：
// *   - 实现 SpringApplicationRunListener 接口
// *   - 构造函数必须接收 SpringApplication 和 String[] args（Spring Boot 自动注入）
// *   - 必须通过 spring.factories 或 AutoConfiguration.imports 注册
// */
//public class InsuranceApplicationRunListener implements SpringApplicationRunListener {
//
//    private static final Logger log = LoggerFactory.getLogger(InsuranceApplicationRunListener.class);
//
//    private final SpringApplication application;
//    private final String[] args;
//
//    /**
//     * 构造函数：必须存在！且参数顺序和类型必须严格匹配
//     * Spring Boot 通过反射自动调用此构造函数，传入 SpringApplication 实例和命令行参数
//     *
//     * @param application Spring Boot 启动器实例
//     * @param args        命令行参数（如 --spring.profiles.active=prod）
//     */
//    public InsuranceApplicationRunListener(SpringApplication application, String[] args) {
//        this.application = application;
//        this.args = args;
//        log.info("[启动监听器] InsuranceApplicationRunListener 已初始化");
//    }
//
//    /**
//     * 应用启动最开始时调用（最早触发）
//     * 此时：环境变量、配置文件尚未加载，日志系统可能未初始化
//     * 建议：仅记录基础信息，避免使用 logger（可用 System.out）
//     */
//    @Override
//    public void starting() {
//        System.out.println("\n" +
//                "╔══════════════════════════════════════════════════════════════════╗\n" +
//                "║ 🏦 人身保险核心系统启动监听器 - 启动审计 (InsuranceAudit)          ║\n" +
//                "║  时间: " + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")) + "          ║\n" +
//                "║  版本: v2.1.0 (Build: 20251018)                                  ║\n" +
//                "║  环境: " + (System.getProperty("spring.profiles.active") != null ? System.getProperty("spring.profiles.active") : "未指定") + "              ║\n" +
//                "╚══════════════════════════════════════════════════════════════════╝\n");
//
//        log.info("[starting] 应用启动流程已开始，执行环境审计...");
//    }
//
//    /**
//     * 环境（Environment）准备完成后调用
//     * 此时：application.yaml / application.properties 已加载，可以安全读取配置
//     * 建议：校验敏感配置是否存在、是否符合 GDPR 要求
//     */
//    @Override
//    public void environmentPrepared(ConfigurableEnvironment environment) {
//        log.info("[environmentPrepared] 环境已加载，开始校验合规性配置...");
//
//        // ✅ 示例1：检查是否配置了 GDPR 数据脱敏开关
//        boolean gdprEnabled = environment.getProperty("insurance.gdpr.enabled", boolean.class, false);
//        if (!gdprEnabled) {
//            log.warn("⚠️  GDPR 数据保护功能未启用！请在 application.yaml 中设置: insurance.gdpr.enabled=true");
//        }
//
//        // ✅ 示例2：检查数据库连接字符串是否包含明文密码
//        String dbUrl = environment.getProperty("spring.datasource.url", "");
//        if (dbUrl != null && dbUrl.contains("password=")) {
//            log.error("❌ 数据库连接字符串中包含明文密码！请使用 Vault 或 Secrets Manager 替代");
//        }
//
//        // ✅ 示例3：记录启动参数
//        if (args != null && args.length > 0) {
//            log.info("启动参数: {}", java.util.Arrays.toString(args));
//        }
//    }
//
//    /**
//     * ApplicationContext 已创建，但未刷新（Bean 尚未初始化）
//     * 此时可以修改 BeanDefinition，但不能注入 Bean
//     */
//    @Override
//    public void contextPrepared(ConfigurableApplicationContext context) {
//        log.info("[contextPrepared] ApplicationContext 已创建，准备加载 Bean 定义...");
//    }
//
//    /**
//     * ApplicationContext 加载完成（所有 @Configuration 类解析完毕）
//     * 可以访问 BeanDefinition，但不能获取 Bean 实例
//     */
//    @Override
//    public void contextLoaded(ConfigurableApplicationContext context) {
//        log.info("[contextLoaded] 所有配置类已加载，共 {} 个 BeanDefinition", context.getBeanDefinitionCount());
//    }
//
//    /**
//     * ApplicationContext 刷新完成（Bean 实例化完成）
//     * 此时所有 @Component、@Service、@Repository 已创建，但 ApplicationRunner 未执行
//     */
//    @Override
//    public void started(ConfigurableApplicationContext context) {
//        log.info("[started] Spring 容器已启动，Bean 已初始化完成");
//    }
//
//    /**
//     * 应用完全运行（ApplicationRunner 和 CommandLineRunner 执行完毕）
//     * 此时应用已“就绪”，适合发送通知、注册到服务发现
//     */
//    @Override
//    public void running(ConfigurableApplicationContext context) {
//        log.info("[running] ✅ 应用已成功启动并运行，准备通知运维系统...");
//
//        // ✅ 示例：向内部监控平台发送启动成功信号（伪代码）
//        // MonitoringService.notifyStartup(context.getId(), "SUCCESS", LocalDateTime.now());
//
//        // ✅ 示例：记录启动耗时（可结合 starting() 中的时间戳）
//        // log.info("启动总耗时: {} ms", System.currentTimeMillis() - startTime);
//    }
//
//    /**
//     * 启动失败时调用
//     * 可用于发送告警、记录异常堆栈、触发回滚流程
//     */
//    @Override
//    public void failed(ConfigurableApplicationContext context, Throwable exception) {
//        log.error("[failed] 应用启动失败！异常信息如下：", exception);
//
//        // ✅ 示例：发送企业微信/钉钉告警（异步）
//        // AlarmService.sendAlert("保险核心系统启动失败", exception.getMessage());
//
//        // ✅ 示例：写入审计日志文件（独立于 Spring 日志系统）
//        // AuditLogWriter.writeFailureLog(exception);
//    }
//}